﻿using System;
using System.Collections.Generic;

namespace Athena.Convertible.Implementations
{
    using Serialization;

    /// <summary>
    /// 默认类型转换Provider
    /// </summary>
    public class DefaultTypeConvertibleProvider : ITypeConvertibleProvider
    {
        private readonly ISerializer<string> _serializer;
        public DefaultTypeConvertibleProvider(ISerializer<string> serializer)
        {
            _serializer = serializer;
        }

        /// <summary>
        /// 创建转换委托
        /// </summary>
        /// <returns></returns>
        public IEnumerable<TypeConvertDelegate> CreateConverts()
        {
            yield return EnumTypeConvert;
            yield return PrimitiveTypeConvert;
            yield return ComplexTypeConvert;
        }

        /// <summary>
        ///  枚举类型转换
        /// </summary>
        /// <param name="instance"></param>
        /// <param name="conversionType"></param>
        /// <returns></returns>
        public static object EnumTypeConvert(object instance, Type conversionType)
        {
            if (instance == null || !conversionType.IsEnum)
            {
                return null;
            }
            return Enum.Parse(conversionType, instance.ToString());
        }

        /// <summary>
        /// 基元类型转换
        /// </summary>
        /// <param name="instance"></param>
        /// <param name="conversionType"></param>
        /// <returns></returns>
        public static object PrimitiveTypeConvert(object instance, Type conversionType)
        {
            if (instance is IConvertible && typeof(IConvertible).IsAssignableFrom(conversionType))
            {
                return Convert.ChangeType(instance, conversionType);
            }
            return null;
        }

        /// <summary>
        /// 普通类型转换
        /// </summary>
        /// <param name="instance"></param>
        /// <param name="conversionType"></param>
        /// <returns></returns>
        private object ComplexTypeConvert(object instance, Type conversionType)
        {
            return _serializer.Deserialize(instance.ToString(), conversionType);
        }
    }
}
